package cn.org.xuanguang.kepler.hormos.rdb.plugin.postgre;

import cn.org.xuanguang.kepler.hormos.rdb.dsl.sql.PrepareSqlFragments;
import cn.org.xuanguang.kepler.hormos.rdb.plugin.DdlSQLBuilder;
import cn.org.xuanguang.kepler.metadata.relational.KeplerMetaColumn;
import cn.org.xuanguang.kepler.metadata.relational.KeplerMetaTable;

import java.sql.JDBCType;

/**
 * pg de ddl 模板,生成各种 ddl 语句
 *
 * @author jarod
 */
public class PgDdlBuilder implements DdlSQLBuilder {

    @Override
    public String getCreateDatabaseDDL(String databaseName) {
        if (databaseName != null) {
            return "CREATE DATABASE IF NOT EXISTS " + databaseName;
        }
        return "";
    }

    @Override
    public String getCreateDatabaseDDL(String databaseName, String charset) {
        if (databaseName != null) {
            return "CREATE DATABASE IF NOT EXISTS " + databaseName + " DEFAULT CHARSET " + charset;
        }
        return "";
    }


    @Override
    public String getDropDatabaseDDL(String databaseName) {
        return "";
    }

    @Override
    public String getCreateTableDDL(String databaseName, String tableName) {
        return "";
    }

    @Override
    public String getCreateTableDDL(KeplerMetaTable keplerMetaTable) {
        //PostgreSQL中创建表的标准语法
        /*
         * CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] table_name (
         *     { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
         *     | table_constraint
         *     | [ CONSTRAINT constraint_name ] UNIQUE ( column_name [, ... ] ) [ constraint_parameters ]
         *     | [ CONSTRAINT constraint_name ] PRIMARY KEY ( column_name [, ... ] ) [ constraint_parameters]
         *     | [ CONSTRAINT constraint_name ] CHECK ( expression )
         *     | [ CONSTRAINT constraint_name ] FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ]
         *     | [ CONSTRAINT constraint_name ] DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE
         *     | [ table_constraint [ ... ] ]
         *     | [ table_constraint [ ... ] ]
         * );
         *
         */
        PrepareSqlFragments sqlFragments = PrepareSqlFragments.of("CREATE");

        sqlFragments.addSql("TABLE IF NOT EXISTS ");

        sqlFragments.addSql(getTable(keplerMetaTable));
        sqlFragments.addSql("(");
        keplerMetaTable.getColumns().forEach(column -> {
            sqlFragments.addSql(column.getColumnName());

            // 添加数据类型，如果有长度，添加长度
            sqlFragments.addSql(getDataType(column.getJdbcType()));
            if (column.getColumnLength() != null) {
                sqlFragments.addSql("(");
                sqlFragments.addSql(String.valueOf(column.getColumnLength()));
                sqlFragments.addSql(")");
            }
            // 主键
            if (column.isPrimaryKey()) {
                sqlFragments.addSql("PRIMARY KEY");
            }
            // nullable
            if (column.isNullable()) {

            } else {
                sqlFragments.addSql("NOT NULL");
            }
            if (!"".equals(column.getDefaultValue())) {
                sqlFragments.addSql("DEFAULT");
                sqlFragments.addSql(column.getDefaultValue());
            }
            //uniqu
            if (column.isUnique()) {
                sqlFragments.addSql("UNIQUE");
            }
            //comment
            if (!"".equals(column.getComment())) {
                sqlFragments.addSql("COMMENT");
                sqlFragments.addSql("'" + column.getComment() + "'");
            }
            sqlFragments.addSql(",");

        });
//        // 添加约束 pg约束模板
//        sqlFragments.addSql("CONSTRAINT");
//        sqlFragments.addSql("PRIMARY KEY");
//        sqlFragments.addSql("(");
//        keplerMetaTable.getColumns().forEach(column -> {
//            if (column.isPrimaryKey()) {
//                sqlFragments.addSql(column.getColumnName());
//                sqlFragments.addSql(",");
//            }
//        });
        sqlFragments.removeLastSql();
        sqlFragments.addSql(")");
        //添加表的注解
        if (!"".equals(keplerMetaTable.getComment())) {
            sqlFragments.addSql("COMMENT");
            sqlFragments.addSql("'" + keplerMetaTable.getComment() + "'");
        }


        sqlFragments.addSql(";");
        return sqlFragments.toRequest().getSql();
    }

    /**
     *  列出postgreSQL数据类型，并添加长度，完成数据转换
     * @param keplerMetaColumn
     * @return
     */
    @Override
    public String getDbDataType(KeplerMetaColumn keplerMetaColumn) {
        if (keplerMetaColumn.getJdbcType() == JDBCType.VARCHAR) {
            return "VARCHAR(" + keplerMetaColumn.getColumnLength() + ")";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.CHAR) {
            return "CHAR(" + keplerMetaColumn.getColumnLength() + ")";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.LONGVARCHAR) {
            return "TEXT";
        }
//        INTEGER
        if (keplerMetaColumn.getJdbcType() == JDBCType.INTEGER) {
            return "INTEGER";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.BIGINT) {
            return "BIGINT";
        }
//       DATE
        if (keplerMetaColumn.getJdbcType() == JDBCType.DATE) {
            return "DATE";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.TIMESTAMP) {
            return "TIMESTAMP";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.TIME) {
            return "TIME";
        }
        if (keplerMetaColumn.getJdbcType() == JDBCType.BOOLEAN) {
            return "BOOLEAN";
        }
//        decimal
        if (keplerMetaColumn.getJdbcType() == JDBCType.DECIMAL) {
            return "DECIMAL(" + keplerMetaColumn.getColumnLength() + "," + keplerMetaColumn.getScale() + ")";
        }

        return "";
    }

    @Override
    public String getDropTableDDL(KeplerMetaTable keplerMetaTable) {
        return "";
    }

    @Override
    public String getAlterTableDDL(KeplerMetaTable keplerMetaTable) {
        return "";
    }

    @Override
    public String getCreateIndexDDL(KeplerMetaTable keplerMetaTable) {
        return "";
    }

    @Override
    public String getDropIndexDDL(KeplerMetaTable keplerMetaTable) {
        return "";
    }

    @Override
    public String getRenameTableDDL(String databaseName, String oldTableName, String newTableName) {
        return "";
    }

    private String getDataType(JDBCType columnType) {
        switch (columnType) {
            case VARCHAR:
                return "VARCHAR";
            case INTEGER:
                return "INTEGER";
            case BIGINT:
                return "BIGINT";
            case DATE:
                return "DATE";
            case TIMESTAMP:
                return "TIMESTAMP";
            case TIME:
                return "TIME";
            case BOOLEAN:
                return "BOOLEAN";
            case DECIMAL:
                return "DECIMAL";
            case FLOAT:
        }
        throw new RuntimeException("不支持的数据类型");
        /*
         *  CREATE TABLE IF NOT EXISTS "public"."t_user" (
         *      "id" SERIAL PRIMARY KEY,
         *      "name" VARCHAR(255) NOT NULL,
         *      "age" INTEGER NOT NULL,
         *      "create_time" TIMESTAMP NOT NULL,
         *      "update_time" TIMESTAMP NOT NULL,
         *      "is_delete" BOOLEAN NOT NULL DEFAULT FALSE
         *  );
         */
    }

    private String getTable(KeplerMetaTable keplerMetaTable) {
        return keplerMetaTable.getSchemaTableName();
    }
}
